#ifndef _RAWVEC6232011_H_
#define _RAWVEC6232011_H_

template <typename T>
struct RawV4
{
	static const int DEMENSION = 4;
	typedef T Type;

	union {
		struct { Type x, y, z, w; };
		Type data[DEMENSION];
	};

	RawV4():x(0), y(0), z(0), w(1){};
	RawV4(Type _x, Type _y, Type _z, Type _w = 1):
		x(_x), y(_y), z(_z), w(_w){};

	inline void adjust() { /*x/=w; y/=w, z/=w;*/ w=1; }
	inline Type factor() const{ return w; }

	void normalize() {
		if (w != 0) {
			x /= w; y /= w; z /= w;
		}
	}

	RawV4 det(const RawV4 _o) {
		Type fac = w*_o.w;
		if (fac == 0) fac = 1;
		return RawV4((y*_o.z-z*_o.y)/fac, (z*_o.x-x*_o.z)/fac, (x*_o.y-y*_o.x)/fac, 1);
	}
};

template <typename T>
struct RawV3
{
	static const int DEMENSION = 3;
	typedef T Type;

	union {
		struct { Type x, y, z; };
		Type data[DEMENSION];
	};

	RawV3(): x(0), y(0), z(0){};
	RawV3(Type _x, Type _y, Type _z):
		x(_x), y(_y), z(_z){};

	inline void adjust();
	inline Type factor() const { return 1; }

	RawV3 det(const RawV3 _o) {
		return RawV4(y*_o.z-z*_o.y, z*_o.x-x*_o.z, x*_o.y-y*_o.x);
	}
};

template <typename T>
struct RawV2
{
	static const int DEMENSION = 2;
	typedef T Type;

	union {
		struct { Type x, y; };
		Type data[DEMENSION];
	};

	RawV2(): x(0), y(0){};
	RawV2(Type _x, Type _y):
	x(_x), y(_y){};

	inline void adjust();
	inline Type factor() const { return 1; }

	Type cross(const RawV2& _o) {
		return x*_o.y - y*_o.x;
	}
};
typedef RawV4<float> float4;
typedef RawV3<float> float3;
typedef RawV2<float> float2;
typedef RawV4<int> int4;
typedef RawV3<int> int3;
typedef RawV2<int> int2;

#endif //_RAWVEC6232011_H_